package cn.shujuhai.qtadmin.platform.pluging.security;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jetbrains.annotations.NotNull;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;

import cn.hutool.core.text.CharSequenceUtil;
import cn.shujuhai.qtadmin.platform.kit.Constant;

/**
 * 验证码校验
 *
 * @author dch798
 * @date 2021/08/27 21:33
 **/
@Component
public class CaptchaCodeFilter extends OncePerRequestFilter {
    public static final String USER_DO_LOGIN = "/user/doLogin";
    private static final String CAPTCHA = "captcha";
    final MyAuthenticationFailureHandler myAuthenticationFailureHandler;

    public CaptchaCodeFilter(MyAuthenticationFailureHandler myAuthenticationFailureHandler) {
        this.myAuthenticationFailureHandler = myAuthenticationFailureHandler;
    }

    /**
     * Same contract as for {@code doFilter}, but guaranteed to be just invoked once per request within a single request
     * thread. See {@link #shouldNotFilterAsyncDispatch()} for details.
     * <p>
     * Provides HttpServletRequest and HttpServletResponse arguments instead of the default ServletRequest and
     * ServletResponse ones.
     *
     * @param request
     *            request
     * @param response
     *            response
     * @param filterChain
     *            filterChain
     */
    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response,
        @NotNull FilterChain filterChain) throws ServletException, IOException {
        if (CharSequenceUtil.equals(USER_DO_LOGIN, request.getRequestURI())
            && CharSequenceUtil.equalsIgnoreCase(request.getMethod(), "post")) {
            try {
                verify(new ServletWebRequest(request));
            } catch (AuthenticationException ex) {
                ex.printStackTrace();
                myAuthenticationFailureHandler.onAuthenticationFailure(request, response, ex);
                return;
            }
        }
        filterChain.doFilter(request, response);
    }

    private void verify(@NotNull ServletWebRequest request) throws ServletRequestBindingException {
        if (!CharSequenceUtil.equals(ServletRequestUtils.getStringParameter(request.getRequest(), CAPTCHA),
            (String)request.getRequest().getSession().getAttribute(Constant.CAPTCHA_SESSION_KEY))) {
            throw new SessionAuthenticationException("验证码不正确");
        }
    }
}
